//
// Created by HhL on 2020/12/23.
//

#include "thread_pool.h"
#include "common.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>


/* 声明线程池 */
pthread_pool g_pthread_pool;

/**
 * 工作线程函数
 *
 * @param arg
 * @return
 */
void *worker_thread_fn(void *arg) {

    print_nobuffer("我是工作线程\n");

    return (void *) 0;
}

/**=====================================
 * 线程池相关操作函数
 ======================================*/

jint thread_pool_init(JNIEnv *jEnv, jint minSize, jint maxSize) {
    /* 为线程池申请内存 */
    g_pthread_pool = calloc(1, sizeof(thread_pool));
    if (NULL == g_pthread_pool) {
        throwRuntimeException(jEnv, "为线程池分配内存失败");

        goto return1;
    }
    /* 为工作线程集合分配内存 */
    g_pthread_pool->worker_tids = calloc(maxSize, sizeof(pthread_t));
    if (NULL == g_pthread_pool->worker_tids) {
        throwRuntimeException(jEnv, "为工作线程集合分配内存失败");

        goto return2;
    }
    /* 初始化互斥锁 */
    if (0 != pthread_mutex_init(&g_pthread_pool->lock, NULL)) {
        throwRuntimeException(jEnv, "初始化互斥锁失败");

        goto return3;
    }
    //对线程池赋值
    g_pthread_pool->thr_min_size = minSize;
    g_pthread_pool->thr_max_size = maxSize;
    g_pthread_pool->thr_live_size = minSize;
    g_pthread_pool->thr_busy_size = 0;
    /* 根据线程池的存活线程数启动最小工作线程 */

    for (int i = 0; i < g_pthread_pool->thr_live_size; ++i) {
        pthread_create(&g_pthread_pool->worker_tids[i], NULL, worker_thread_fn, NULL);
    }
    return 0;
return3:
    free(g_pthread_pool->worker_tids);
    g_pthread_pool->worker_tids = NULL;


return2:
    free(g_pthread_pool);
    g_pthread_pool = NULL;


return1:
    return -1;
}

void thread_pool_destroy() {
    assert(g_pthread_pool != NULL);

    for (int i = 0; i < g_pthread_pool->thr_live_size; ++i) {
        pthread_join(g_pthread_pool->worker_tids[i], NULL);
    }

    thread_pool_free();
}

void thread_pool_free() {
    print_nobuffer("【线程池销毁程序】任务执行结束，开始释放资源");
    pthread_mutex_destroy(&g_pthread_pool->lock);
    free(g_pthread_pool->worker_tids);
    free(g_pthread_pool);

    g_pthread_pool = NULL;
}
void thread_pool_print(const char *msg) {
    assert(msg != NULL);

    char str[BUFSIZ] = {0};

    sprintf(str, "%s: min_size=%d, max_size=%d, live_size=%d, busy_size=%d\n",
            msg, g_pthread_pool->thr_min_size, g_pthread_pool->thr_max_size, g_pthread_pool->thr_live_size, g_pthread_pool->thr_busy_size);

    write(STDOUT_FILENO, str, strlen(str));
}